package net.love5z.web.common.session;

import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.love5z.web.common.cache.GaeCacheService;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

public class GaeCacheSessionHttpRequest extends HttpServletRequestWrapper {

    private static final Logger logger = Logger.getLogger(GaeCacheSessionHttpRequest.class);

    private String              sessionCookieName;

    private int                 sessionExpireMinutes;

    private String              sessionIdPrefix;

    private HttpServletRequest  orgRequest;

    private HttpServletResponse orgResponse;

    private GaeCacheService     gaeCacheService;

    private GaeSession          session;

    public GaeCacheSessionHttpRequest(GaeCacheService gaeCacheService,
                                      HttpServletRequest orgRequest,
                                      HttpServletResponse orgResponse, String sessionCookieName,
                                      int sessionExpireMinutes, String sessionIdPrefix) {
        super(orgRequest);
        this.orgRequest = orgRequest;
        this.orgResponse = orgResponse;
        this.gaeCacheService = gaeCacheService;

        this.sessionCookieName = sessionCookieName;
        this.sessionExpireMinutes = sessionExpireMinutes;
        this.sessionIdPrefix = sessionIdPrefix;
    }

    public HttpSession getSession() {
        return this.getSession(false);
    }

    public HttpSession getSession(boolean create) {

        if (session != null) {
            return session;
        } else {
            String gaeCacheSessionId = null;

            Cookie gaeCacheSessionCookie = CookieUtil.getCookie(orgRequest, this.sessionCookieName);
            if (gaeCacheSessionCookie != null
                && StringUtils.isNotBlank(gaeCacheSessionCookie.getValue())) {

                logger.debug("find gae session cookie from ua");
                gaeCacheSessionId = gaeCacheSessionCookie.getValue();

                session = (GaeSession) gaeCacheService.get(gaeCacheSessionId);
            } else {
                logger.debug("No gae session cookie from ua");
            }

            if (null == session) {
                if (create) {
                    gaeCacheSessionId = this.sessionIdPrefix + ":" + UUID.randomUUID().toString();

                    CookieUtil.setCookie(orgRequest, orgResponse, this.sessionCookieName,
                        gaeCacheSessionId);

                    session = new GaeSession(gaeCacheSessionId);
                    saveGaeSession();
                }
            }

            return session;
        }
    }

    public void saveGaeSession() {
        if (session != null) {
            gaeCacheService.put(session.getId(), (GaeSession) session, sessionExpireMinutes * 60);
        }
    }

}
